{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "34cae875-0dd8-46e8-af7e-b346a7067711",
   "metadata": {},
   "source": [
    "# Arithmetic Expressions\n",
    "\n",
    "Use the `Arithmetic` function to write complex mathematical expression in free format.\n",
    "The notation follows the Python language for math notation.\n",
    "\n",
    "The function first parses the expression and builds an abstract syntax tree (AST). Then, the Classiq engine finds a\n",
    "computation strategy for a specified number of qubits, and compiles the desired quantum program.\n",
    "\n",
    "As opposed to classical computers, when quantum computers evaluate arithmetic\n",
    "expression, the calculations are reversible and are applied on all quantum states in parallel.\n",
    "To do so, quantum computers store all intermediate computation results in a quantum variables.\n",
    "Qubits that are not freed cannot be used later on in the quantum program.\n",
    "\n",
    "Analogously to the classical world, there is a form of quantum \"garbage collection\",\n",
    "usually referred to as uncomputation, which returns the garbage qubits to their original state.\n",
    "The computation strategy determines the order in which qubits are released and reused.\n",
    "By employing different strategies, you can produce a variety of quantum programs with the same functionality.\n",
    "In general, longer quantum programs require less qubits than shorter ones.\n",
    "\n",
    "Supported operators:\n",
    "\n",
    "- Add: `+`\n",
    "- Subtract: `-` (two arguments)\n",
    "- Negate: `-` (a single argument)\n",
    "- Multiply: `*`\n",
    "- Bitwise Or: `|`\n",
    "- Bitwise And: `&`\n",
    "- Bitwise Xor: `^`\n",
    "- Invert: `~`\n",
    "- Equal: `==`\n",
    "- Not Equal: `!=`\n",
    "- Greater Than: `>`\n",
    "- Greater Or Equal: `>=`\n",
    "- Less Than: `<`\n",
    "- Less Or Equal: `<=`\n",
    "- Modulo: `%` limited for power of 2\n",
    "- Logical And: `and`\n",
    "- Logical Or: `or`\n",
    "- Max: `max` (n>=2 arguments)\n",
    "- Min: `min` (n>=2 arguments)\n",
    "- Power `**` (register base, positive int power)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "721738fb-4975-4a39-9b50-1531535b2c75",
   "metadata": {},
   "source": [
    "## Example\n",
    "\n",
    "This example generates a quantum program that calculates the expression `(a + b + c & 15) % 8 ^ 3 & a ^ 10 == 4`.\n",
    "Each of the variables `a`,`b`, and `c` is defined as a quantum varialbe with a different size."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "0bddc7b7-afe0-4fcc-a4f6-d5636c9df559",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T13:21:35.400622Z",
     "iopub.status.busy": "2024-05-07T13:21:35.399568Z",
     "iopub.status.idle": "2024-05-07T13:21:38.409418Z",
     "shell.execute_reply": "2024-05-07T13:21:38.408703Z"
    }
   },
   "outputs": [],
   "source": [
    "from classiq import Output, QArray, QBit, QNum, create_model, prepare_int, qfunc\n",
    "\n",
    "\n",
    "@qfunc\n",
    "def main(a: Output[QNum], b: Output[QNum], c: Output[QNum], res: Output[QNum]) -> None:\n",
    "    prepare_int(2, a)\n",
    "    prepare_int(1, b)\n",
    "    prepare_int(5, c)\n",
    "\n",
    "    res |= (a + b + c & 15) % 8 ^ 3 & a ^ 10 == 4\n",
    "\n",
    "\n",
    "qmod = create_model(main)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "531a28d1-e5c3-467e-9abf-0692d2d5c5cd",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-05-07T13:21:38.412707Z",
     "iopub.status.busy": "2024-05-07T13:21:38.411911Z",
     "iopub.status.idle": "2024-05-07T13:21:42.574449Z",
     "shell.execute_reply": "2024-05-07T13:21:42.573730Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[{'a': 2.0, 'b': 1.0, 'c': 5.0, 'res': 0.0}: 1000]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from classiq import execute, synthesize, write_qmod\n",
    "\n",
    "write_qmod(qmod, \"arithmetic_expression_example\")\n",
    "qprog = synthesize(qmod)\n",
    "\n",
    "result = execute(qprog).result()[0].value\n",
    "result.parsed_counts"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
